package input;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import states.EstadoAccion;
import states.EstadoEntrada;


public class ParserArchivo {
	
	Map<EstadoEntrada,EstadoAccion> transiciones;
	String initialState;

	public ParserArchivo (String filename) throws IOException {

		FileInputStream archivo = new FileInputStream(filename);
		InputStreamReader stream = new InputStreamReader(archivo);
		BufferedReader reader = new BufferedReader(stream);

		transiciones = new HashMap<EstadoEntrada,EstadoAccion> ();

		// Comienza la lectura del archivo.

		String line = null;
		initialState = null;

		while ((line = reader.readLine()) != null) {

			String[] values = line.split(",");

			if (values.length != 4){
				throw new IOException("La linea debe tener 4 campos.");
			}

			// Aca se deberian validar las entradas.

			String origen = validarEstado(values[0]);
			char simbolo = validarSimbolo(values[1]);
			String destino = validarEstado(values[2]);
			char accion = validarAccion(values[3]);

			// Se setea el estado inicial si corresponde.

			if (initialState == null) {
				initialState = origen;
			}

			// Se agrega la transicion leeida.

			EstadoEntrada key = new EstadoEntrada(origen,simbolo);
			if (transiciones.containsKey(key)){
				throw new IOException("Hay mas de una accion para el estado " + origen + " y la entrada "+simbolo);
			}else{
				transiciones.put(key, new EstadoAccion(destino,accion));	
			}
			
		}
	}

	public Map<EstadoEntrada, EstadoAccion> getTransiciones() {
		return transiciones;
	}

	public String getInitialState() {
		return initialState;
	}

	private String validarEstado(String estado) throws IOException {
        if (estado.isEmpty()){
        	throw new IOException("El estado no puede estar vacio.");
        }
		Pattern p = Pattern.compile("^[a-zA-z0-9]*$");
        Matcher m = p.matcher(estado);
        if ( !m.find() ){
        	throw new IOException("El estado -" + estado + "- debe ser alfanumerico.");
        }else{
        	
        }
		return estado;
	}

	private char validarAccion (String entrada) throws IOException {
        if (entrada.isEmpty()){
        	throw new IOException("La accion no puede estar vacia.");
        }
		if (entrada.length()>1){
			throw new IOException("La accion no es valida (tiene mas de un caracter).");
		}
		char accion = entrada.charAt(0);
		if (accion != '>' && accion != '<' && accion != '1' && accion != '2' && accion != '0') {
			throw new IOException("La accion no es valida (solo puede ser 0,1,2,<,>)");
		}
		return accion;
	}

	private char validarSimbolo (String entrada) throws IOException {
        if (entrada.isEmpty()){
        	throw new IOException("El simbolo de entrada no puede estar vacio.");
        }		
		char simbolo = entrada.charAt(0);
		if (simbolo != '1' && simbolo != '2' && simbolo != '0') {
			throw new IOException("El simbolo no es valido (solo puede ser 0,1,2)");
		}
		return simbolo;
	}
}
